home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
remin301.zip
/
REMIN300.ZIP
/
DOSUBST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-10
|
10KB
|
409 lines
/***************************************************************/
/* */
/* DOSUBST.C */
/* */
/* This performs all the "%" substitution functions when */
/* reminders are triggered. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992 by David F. Skoll. */
/* */
/***************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "config.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include "globals.h"
#include "err.h"
#include "types.h"
#include "protos.h"
#define UPPER(c) ( ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c) )
#define ABS(x) ( (x) < 0 ? -(x) : (x) )
#ifndef NL
#define NL "\n"
#endif
static char TODAY[] = "today";
static char TOMORROW[] = "tomorrow";
/***************************************************************/
/* */
/* DoSubst */
/* */
/* Process the % escapes in the reminder. If */
/* mode==NORMAL_MODE, ignore the %" sequence. If */
/* mode==CAL_MODE, process the %" sequence. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoSubst(ParsePtr p, char *out, Trigger *t, TimeTrig *tt, int jul, int mode)
#else
int DoSubst(p, out, t, tt, jul, mode)
ParsePtr p;
char *out;
Trigger *t;
TimeTrig *tt;
int jul, mode;
#endif
{
int diff = jul - JulianToday;
int curtime = SystemTime() / 60;
int err, done;
int c;
int d, m, y;
int tim = tt->ttime;
int h, min, hh, ch, cmin, chh;
char *pm, *cpm;
int tdiff, adiff, mdiff, hdiff;
char *mplu, *hplu, *when, *plu;
int has_quote = 0;
char *s = out;
char *os;
FromJulian(jul, &y, &m, &d);
if (tim == NO_TIME) tim = curtime;
tdiff = tim - curtime;
adiff = ABS(tdiff);
mdiff = adiff % 60;
hdiff = adiff / 60;
mplu = (mdiff == 1 ? "" : "s");
hplu = (hdiff == 1 ? "" : "s");
when = (tdiff < 0 ? "ago" : "from now");
h = tim / 60;
min = tim % 60;
pm = (h < 12) ? "am" : "pm";
hh = (h == 12) ? 12 : h % 12;
ch = curtime / 60;
cmin = curtime % 60;
cpm = (ch < 12) ? "am" : "pm";
chh = (ch == 12) ? 12 : ch % 12;
switch(d) {
case 1:
case 21:
case 31: plu = "st"; break;
case 2:
case 22: plu = "nd"; break;
case 3:
case 23: plu = "rd"; break;
default: plu = "th"; break;
}
while(1) {
c = ParseChar(p, &err, 0);
if (err) return err;
if (c == '\n') continue;
if (!c) {
if (mode != CAL_MODE) *s++ = '\n';
*s++ = 0;
break;
}
if (c != '%') {
*s++ = c;
continue;
}
c = ParseChar(p, &err, 0);
if (err) return err;
if (!c) {
*s++ = 0;
break;
}
os = s;
done = 0;
if (diff <= 1) {
switch(UPPER(c)) {
case 'A':
case 'B':
case 'C':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'U':
case 'V': sprintf(s, "%s", (diff ? TOMORROW : TODAY));
s += strlen(s);
done = 1;
break;
default: done = 0;
}
}
if (!done) switch(UPPER(c)) {
case 'A':
sprintf(s, "on %s, %d %s, %d", DayName[jul%7], d,
MonthName[m], y);
s += strlen(s);
break;
case 'B':
sprintf(s, "in %d days' time", diff);
s += strlen(s);
break;
case 'C':
sprintf(s, "on %s", DayName[jul%7]);
s += strlen(s);
break;
case 'D':
sprintf(s, "%d", d);
s += strlen(s);
break;
case 'E':
sprintf(s, "on %02d/%02d/%04d", d, m+1, y);
s += strlen(s);
break;
case 'F':
sprintf(s, "on %02d/%02d/%04d", m+1, d, y);
s += strlen(s);
break;
case 'G':
sprintf(s, "on %s, %d %s", DayName[jul%7], d, MonthName[m]);
s += strlen(s);
break;
case 'H':
sprintf(s, "on %02d/%02d", d, m+1);
s += strlen(s);
break;
case 'I':
sprintf(s, "on %02d/%02d", m+1, d);
s += strlen(s);
break;
case 'J':
sprintf(s, "on %s, %s %d%s, %d", DayName[jul%7],
MonthName[m], d, plu, y);
s += strlen(s);
break;
case 'K':
sprintf(s, "on %s, %s %d%s", DayName[jul%7],
MonthName[m], d, plu);
s += strlen(s);
break;
case 'L':
sprintf(s, "on %04d/%02d/%02d", y, m+1, d);
s += strlen(s);
break;
case 'M':
sprintf(s, "%s", MonthName[m]);
s += strlen(s);
break;
case 'N':
sprintf(s, "%d", m+1);
s += strlen(s);
break;
case 'O':
if (RealToday == JulianToday) sprintf(s, " (today)");
s += strlen(s);
break;
case 'P':
sprintf(s, (diff == 1 ? "" : "s"));
s += strlen(s);
break;
case 'Q':
sprintf(s, (diff == 1 ? "'s" : "s'"));
s += strlen(s);
break;
case 'R':
sprintf(s, "%02d", d);
s += strlen(s);
break;
case 'S':
sprintf(s, plu);
s += strlen(s);
break;
case 'T':
sprintf(s, "%02d", m+1);
s += strlen(s);
break;
case 'U':
sprintf(s, "on %s, %d%s %s, %d", DayName[jul%7], d,
plu, MonthName[m], y);
s += strlen(s);
break;
case 'V':
sprintf(s, "on %s, %d%s %s", DayName[jul%7], d, plu,
MonthName[m]);
s += strlen(s);
break;
case 'W':
sprintf(s, DayName[jul%7]);
s += strlen(s);
break;
case 'X':
sprintf(s, "%d", diff);
s += strlen(s);
break;
case 'Y':
sprintf(s, "%d", y);
s += strlen(s);
break;
case 'Z':
sprintf(s, "%d", y % 100);
s += strlen(s);
break;
case '1':
if (tdiff == 0)
sprintf(s, "now");
else if (hdiff == 0)
sprintf(s, "%d minute%s %s", mdiff, mplu, when);
else if (mdiff == 0)
sprintf(s, "%d hour%s %s", hdiff, hplu, when);
else
sprintf(s, "%d hour%s and %d minute%s %s", hdiff, hplu, mdiff, mplu, when);
s += strlen(s);
break;
case '2':
sprintf(s, "at %d:%02d%s", hh, min, pm);
s += strlen(s);
break;
case '3': sprintf(s, "at %02d:%02d", h, min);
s += strlen(s);
break;
case '4': sprintf(s, "%d", tdiff);
s += strlen(s);
break;
case '5': sprintf(s, "%d", adiff);
s += strlen(s);
break;
case '6': sprintf(s, when);
s += strlen(s);
break;
case '7': sprintf(s, "%d", hdiff);
s += strlen(s);
break;
case '8': sprintf(s, "%d", mdiff);
s += strlen(s);
break;
case '9': sprintf(s, mplu);
s += strlen(s);
break;
case '0': sprintf(s, hplu);
s += strlen(s);
break;
case '!': sprintf(s, (tdiff >= 0 ? "is" : "was"));
s += strlen(s);
break;
case '@': sprintf(s, "%d:%02d%s", chh, cmin, cpm);
s += strlen(s);
break;
case '#': sprintf(s, "%02d:%02d", ch, cmin);
s += strlen(s);
break;
case '_': sprintf(s, "%s", NL);
s += strlen(s);
break;
case QUOTE_MARKER:
/* Swallow any QUOTE_MARKERs which may somehow creep in... */
break;
case '"':
*s++ = QUOTE_MARKER;
has_quote = 1;
break;
default:
*s++ = c;
}
if (isupper(c)) *os = UPPER(*os);
}
/* We're outside the big while loop. The only way to get here is for c to
be null. Now we go through and delete %" sequences, if it's the
NORMAL_MODE, or retain only things within a %" sequence if it's the
CAL_MODE. */
/* If there are NO quotes, then: If CAL_MODE && RUN_TYPE, we don't want the
reminder in the calendar. Zero the output buffer and quit. */
if (!has_quote) {
if (mode == CAL_MODE && t->typ == RUN_TYPE) *out = 0;
return OK;
}
/* There ARE quotes. If in CAL_MODE, delete everything before first quote
and after second quote. If in NORMAL_MODE, delete the %" sequences. */
s = out;
os = out;
if (mode == NORMAL_MODE) {
while (*s) {
if (*s != QUOTE_MARKER) *os++ = *s;
s++;
}
*os = 0;
} else {
/* Skip past the quote marker */
while (*s && (*s != QUOTE_MARKER)) s++;
/* Security check... actually, *s must == QUOTE_MARKER at this point, but
it doesn't hurt to make it a bit robust. */
if (*s) s++;
/* Copy the output until the next QUOTE_MARKER */
while (*s && (*s != QUOTE_MARKER)) *os++ = *s++;
*os = 0;
}
return OK;
}